package UIComponent
{
	import flash.display.Graphics;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.KeyboardEvent;
	import flash.events.MouseEvent;
	
	import mx.controls.Button;
	import mx.controls.Text;
	import mx.controls.TextArea;
	import mx.core.UIComponent;
	import mx.events.FlexEvent;
	import mx.events.PropertyChangeEvent;
	
	import spark.components.HGroup;
	import spark.components.Label;
	import spark.components.TextInput;

	public class DynamicLabel extends UIComponent
	{
		//component
		private var label:Label;
		private var textBox:TextInput;
		private var richBox:TextArea;
		private var panel:HGroup;
		private var enter:Button;
		private var cancel:Button;
		
		//status
		private var d_width:int=new int();
		private var d_height:int=new int();
		private var style:int=new int();
		private var background:Boolean=false;
		private var active:Boolean=false;
		
		//event dispatcher
		private var _eventDispatcher:EventDispatcher=null;
		
		//static
		private var LABEL_DEFAULT:String="Default";
		//static private var LABEL_DEFAULT_WIDTH:Number=120;
		static private var LABEL_DEFAULT_HEIGHT:Number=12;
		
		
		private var TEXTBOX_DEFAULT_WIDTH:Number;  //auto calculated
		//private var TEXTBOX_DEFAULT_HEIGHT:Number=18;
		
		private var MARGIN_WIDTH:Number=1;
		private var MARGIN_HEIGHT:Number=1;
		private var BUTTON_WIDTH:Number=25;
		private var BUTTON_HEIGHT:Number=18;
		
		
		public function DynamicLabel(_style:int = 0, _width:Number = 120, _height:Number = 20)
		{
			//basic item
			label=new Label();
			label.text=LABEL_DEFAULT;
			this.addChild(label);
			style=_style;
			
			//set label layout
			if(style == 0)
			{
				d_width = _width;
				d_height = _height;
				
				//@todo add min width and height test
				label.x=MARGIN_WIDTH;
				label.y= MARGIN_HEIGHT + (d_height - LABEL_DEFAULT_HEIGHT)/2;
				label.width=d_width - MARGIN_WIDTH*2;
				label.height=d_height - MARGIN_HEIGHT*2;
			}
			else
			{
				d_width=_width;
				d_height=_height;
				if(d_height < BUTTON_HEIGHT)
				{
					d_height = BUTTON_HEIGHT * 2 + MARGIN_HEIGHT*3;
				}
				
				//@todo add min width test
				
				label.x=MARGIN_WIDTH;
				label.y=MARGIN_HEIGHT;
				label.width= d_width - MARGIN_WIDTH*2;
				label.height= d_height - MARGIN_WIDTH*2;

			}
			
			//event
			label.doubleClickEnabled=true;
			label.addEventListener(MouseEvent.CLICK,onClickLabel);
			_eventDispatcher=new EventDispatcher();
		}
		
		override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
		{
			var g2d:Graphics=this.graphics;
			g2d.clear();
			
			if(background==true && active==false)
			{
				g2d.beginFill(0xEEEEEE);
				g2d.drawRoundRect(0,0,d_width,d_height,4);
				g2d.endFill();
			}
			
			super.updateDisplayList(unscaledWidth,unscaledHeight);
			
		}
		
		protected function onClickLabel(evt:MouseEvent):void
		{
			label.visible=false;
			active=true;
			
			//add input box	
			if(style == 0)
			{
				textBox=new TextInput();
				this.addChild(textBox);
				textBox.text=label.text;
				textBox.addEventListener(KeyboardEvent.KEY_DOWN, onPressKey);
				textBox.x=MARGIN_WIDTH;
				textBox.y=MARGIN_HEIGHT;
				textBox.width=d_width - BUTTON_WIDTH*2 - MARGIN_WIDTH*4;
				textBox.height=d_height - MARGIN_HEIGHT*2;
			}
			else
			{
				richBox=new TextArea();
				this.addChild(richBox);
				richBox.text=label.text;
				richBox.addEventListener(KeyboardEvent.KEY_DOWN,onPressKey);
				richBox.x=MARGIN_WIDTH;
				richBox.y=MARGIN_HEIGHT;
				richBox.width= d_width - MARGIN_WIDTH*2;
				richBox.height= d_height - BUTTON_HEIGHT - MARGIN_HEIGHT*3;
			}
			
			//add button
			enter=new Button();
			this.addChild(enter);
			enter.label="v";
			enter.addEventListener(MouseEvent.CLICK,onClickOK);
			if(style==0)
			{
				enter.x=d_width - BUTTON_WIDTH*2 - MARGIN_WIDTH*2;
				enter.y= MARGIN_HEIGHT;
				enter.width=BUTTON_WIDTH;
				enter.height=BUTTON_HEIGHT;
			}
			else
			{
				enter.x= d_width - BUTTON_WIDTH*2 - MARGIN_WIDTH*2;
				enter.y= d_height - BUTTON_HEIGHT - MARGIN_HEIGHT;
				enter.width= BUTTON_WIDTH;
				enter.height= BUTTON_HEIGHT;
			}
			
			
			cancel=new Button();
			this.addChild(cancel);
			cancel.label="x";
			cancel.addEventListener(MouseEvent.CLICK,onClickCancel);
			if(style==0)
			{
				cancel.x= d_width - BUTTON_WIDTH - MARGIN_WIDTH;
				cancel.y= MARGIN_HEIGHT;
				cancel.width=BUTTON_WIDTH;
				cancel.height=BUTTON_HEIGHT;
			}
			else
			{
				cancel.x= d_width - BUTTON_WIDTH - MARGIN_WIDTH;
				cancel.y= d_height - BUTTON_HEIGHT - MARGIN_HEIGHT;
				cancel.width=BUTTON_WIDTH;
				cancel.height=BUTTON_HEIGHT;
			}
		}
		
		protected function onClickOK(evt:MouseEvent):void
		{
			confirmInput();
		}
		
		protected function onClickCancel(evt:MouseEvent):void
		{
			cancelInput();
		}
		
		protected function onPressKey(evt:KeyboardEvent):void
		{
			switch(evt.keyCode)
			{
				case 13:		//Enter
					if(style ==0)
					{
						confirmInput();
					}
					break;
				case 27:		//ESC
					cancelInput();
					break;
				default:
			}
		}
		
		private function confirmInput():void
		{
			active=false;
			label.visible=true;
			if(style ==0 )
			{
				label.text=textBox.text;
				this.removeChild(textBox);
				textBox=null;
			}
			else
			{
				label.text=richBox.text;
				this.removeChild(richBox);
				richBox=null;
			}

			this.removeChild(enter);
			this.removeChild(cancel);
			enter=null;
			cancel=null;
			
			var evt:PropertyChangeEvent=new PropertyChangeEvent(PropertyChangeEvent.PROPERTY_CHANGE);
			evt.newValue=label.text;
			_eventDispatcher.dispatchEvent(evt);
			this.invalidateDisplayList();
			
		}
		
		private function cancelInput():void
		{
			label.visible=true;
			active=false;
			if(style == 0)
			{
				this.removeChild(textBox);
				textBox=null;
			}
			else
			{
				this.removeChild(richBox);
				richBox=null;
			}
			
			this.removeChild(enter);
			this.removeChild(cancel);
			enter=null;
			cancel=null;
			
			this.invalidateDisplayList();
		}
				
		public function getWidth():int
		{
			return d_width;
		}
		
		public function setText(_text:String):void
		{
			label.text=_text;
		}

		public function setEventListener(type : String ,listener : Function):void
		{
			this._eventDispatcher.addEventListener(type,listener);
		}
		
		public function showBackground(_isShow:Boolean):void
		{
			background=_isShow;
		}
	}
}